package com.xbp.examsystem.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xbp.examsystem.entity.Category;
import com.xbp.examsystem.entity.Question;
import com.xbp.examsystem.exception.ExamException;
import com.xbp.examsystem.mapper.CategoryMapper;
import com.xbp.examsystem.mapper.QuestionMapper;
import com.xbp.examsystem.service.CategoryService;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Autowired
    private QuestionMapper questionMapper;



    @Override
    public List<Category> getCategoryList() {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.orderByAsc(Category::getSort);
        List<Category> categoryList = baseMapper.selectList(categoryLambdaQueryWrapper);

        addCategoryCount(categoryList);
        return categoryList;
    }

    private void addCategoryCount(List<Category> categoryList) {
        List<Map<Long, Long>> categoryCount = questionMapper.getCategoryCount();
        Map<Long, Long> categoryMap = categoryCount.stream().collect(Collectors.toMap(
                k -> k.get("category_id"),
                v -> v.get("count")
        ));
        categoryList.forEach(category -> {
            Long orDefault = categoryMap.getOrDefault(category.getId(), 0L);
            category.setCount(orDefault);
        });
    }

    @Override
    public List<Category> getCategoryTree() {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.orderByAsc(Category::getSort);
        List<Category> categoryList = baseMapper.selectList(categoryLambdaQueryWrapper);
        addCategoryCount(categoryList);

        return buildCategoryTree(categoryList);
    }

    @NotNull
    private static List<Category> buildCategoryTree(List<Category> categoryList) {
        Map<Long, List<Category>> longListMap = categoryList.stream().collect(Collectors.groupingBy(Category::getParentId));
        categoryList.forEach(category -> {
            Long id = category.getId();
            List<Category> orDefault = longListMap.getOrDefault(id, new ArrayList<>());
            category.setChildren(orDefault);
            long sum = orDefault.stream().mapToLong(Category::getCount).sum();
            Long count = category.getCount();
            category.setCount(sum+count);
        });
        List<Category> collect = categoryList.stream().filter(category -> category.getParentId() == 0).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void addCategory(Category category) {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.eq(Category::getParentId,category.getParentId()).eq(Category::getName,category.getName());
        boolean b = baseMapper.exists(categoryLambdaQueryWrapper);
        if(b){
            throw new ExamException(666,category.getName()+"已存在");
        }
        baseMapper.insert(category);

    }

    @Override
    public void updateCategory(Category category) {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.eq(Category::getParentId,category.getParentId()).eq(Category::getName,category.getName()).ne(Category::getId,category.getId());
        boolean b = baseMapper.exists(categoryLambdaQueryWrapper);
        if(b){
            throw new ExamException(666,category.getName()+"已存在");
        }
        category.setUpdateTime(new Date());
        baseMapper.updateById(category);

    }

    @Override
    public void deleteCategory(Long id) {
        LambdaQueryWrapper<Category> categoryLambdaQueryWrapper = new LambdaQueryWrapper<>();
        categoryLambdaQueryWrapper.eq(Category::getParentId,id);
        Long l = baseMapper.selectCount(categoryLambdaQueryWrapper);
        if(l>0){
            throw new ExamException(777,"该类下有子分类，不能删除");
        }
        Long l1 = questionMapper.selectCount(new LambdaQueryWrapper<Question>().eq(Question::getCategoryId, id));
        if(l1>0){
            throw new ExamException(888,"该子分类下有题目，不能删除");
        }
        baseMapper.deleteById(id);

    }
}